home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir30 / alsps.zip / ALSP8.DOC < prev    next >
Lisp/Scheme  |  1993-11-04  |  7KB  |  220 lines

  1. This is Lesson 8 of a series of AutoLISP training exercises given
  2. on the CompuServe ADESK Forum by the Autodesk, Inc. Training
  3. Department.
  4.  
  5. PREDICATES, LOGICAL OPERATORS, AND CONDITIONAL EXPRESSIONS, PART
  6. ONE
  7.  
  8. BRANCHING
  9.  
  10. The ability to examine the state of one or more settings (or
  11. variables) and make a decision based on the state(s) whether or
  12. not to execute a program expression is a fundamental and
  13. powerful facility in AutoLISP.  This form of decision-making may
  14. be referred to as a conditional branch, that is, a branch in the
  15. program logic to execute or not execute a particular program
  16. expression, or to execute one program expression rather than
  17. another, based on some condition that exists.
  18.  
  19. You and I make these kinds of decisions all the time.  If it is
  20. sunny today, I will not take my umbrella with me to work.  If the
  21. gasoline costs less at a given service station, then I will
  22. purchase gasoline there, rather than at another station.
  23.  
  24. In both of the previous examples, the word "if" is used as the
  25. conditional expression, that is, the function that performs a
  26. test to determine whether a particular state or condition exists.
  27. The AutoLISP subr IF has virtually the same meaning as its use in
  28. the previous, real-world examples.
  29.  
  30. THE IF STATEMENT
  31.  
  32. The subr IF is used to test the state of a single condition.  If
  33. the condition evaluates to a non-nil value, that is, anything BUT
  34. nil, then the program expression immediately following the test
  35. will be executed.
  36.  
  37.     (if <test expression> <expression> [<expression>])
  38.  
  39. There must be one expression following the test expression.
  40. Optionally, there may be a second expression that will be
  41. evaluated if the test expression returns nil.
  42.     
  43. For example, this is the definition of a function to test whether
  44. the value of variable X is greater than 0.  If it is, then it
  45. prints the statement "X greater than 0" on the display.
  46.  
  47. Edit a new file named GREATER.LSP and define this function.
  48.  
  49.     (defun GREATER ()
  50.       (if
  51.         (> x 0)
  52.         (prompt "\nX is greater than 0.")
  53.       )
  54.       (prin1)
  55.     )
  56.  
  57.     Command: (setq x 1)
  58.     1
  59.  
  60.     Command: (load "greater")
  61.     GREATER
  62.  
  63.     Command: (greater)
  64.     X is greater than 0.
  65.  
  66.     Command: (setq x -1)
  67.     -1
  68.  
  69.     Command: (greater)
  70.  
  71. There are a couple of things you can do to make the GREATER
  72. function more versatile.  First, make the value to be tested a
  73. required argument to the function, so that GREATER doesn't depend
  74. on the value of a particular global variable named X.  Next, add
  75. a second statement to the IF expression that prints a message if
  76. the value of the required argument is LESS then or EQUAL TO zero.
  77.  
  78. Edit the file GREATER.LSP and make these two changes to the
  79. GREATER function.
  80.  
  81.     (defun GREATER (x)
  82.       (if
  83.         (> x 0)
  84.         (print "\nArgument is greater than 0.")
  85.         (print "\nArgument is less than or equal to 0.")
  86.       )
  87.       (prin1)
  88.     )
  89.  
  90.     Command: (load "greater")
  91.     GREATER
  92.  
  93.     Command: (greater 1)
  94.     Argument is greater than 0.
  95.  
  96.     Command: (greater -1)
  97.     Argument is less than or equal to 0.
  98.  
  99.     Command: (setq y 1)
  100.     1
  101.  
  102.     Command: (greater y)
  103.     Argument is greater than 0.
  104.  
  105. A PRACTICAL USE FOR IF
  106.  
  107. One of the recent topics on the CompuServe ADESK Forum has been
  108. the desire to change the END command so that it prompts the user
  109. whether or not to really save the current state of the drawing
  110. and exit the drawing editor, in the same manner that QUIT prompts
  111. the user.
  112.  
  113. In the following example, you will write an AutoLISP function to
  114. substitute for the native AutoCAD END command, and undefined the
  115. native END command so that AutoCAD will use the AutoLISP function
  116. in its place.
  117.  
  118. The new function will be defined so that it can be called
  119. directly from the AutoCAD command prompt without first being
  120. enclosed in parentheses, and will itself call the native END
  121. command (regardless of whether END has been undefined) by
  122. prefacing the command name with a period ".".
  123.  
  124. Edit a new file named END.LSP and add this function.
  125.  
  126.     (defun C:END (/ usr)
  127.  
  128.       ; prompt the user and get a response
  129.       (setq usr (getstring "\nReally want to END the drawing? "))
  130.  
  131.       ; convert his response to upper case characters
  132.       (setq usr (strcase usr))
  133.  
  134.       ; test whether his response was "y" or "Y"
  135.       (if
  136.         (equal "Y" usr)
  137.  
  138.       ; if it was, then end the drawing, else print message
  139.         (command ".END")
  140.         (prompt "\nRemaining in drawing editor.")
  141.       )
  142.       
  143.       ; quiet exit if answer is anything but "y" or "Y"
  144.       (prin1)
  145.     )
  146.  
  147. UNDEFINE the native END command so that is may be replaced by the
  148. AutoLISP-based C:END function (for more information about the
  149. UNDEFINE command, please see your AutoCAD Reference Manual).
  150.  
  151.     Command: UNDEFINE
  152.     Command name: END
  153.  
  154.     Command: (load "end")
  155.     C:END
  156.  
  157.     Command: END
  158.     Really want to END the drawing? n
  159.     Remaining in drawing editor.
  160.  
  161.     Command: END
  162.     Really want to END the drawing? y
  163.  
  164. For the sake of efficiency and avoiding unnecessary variable
  165. binding, which can be relatively expensive in terms of computer
  166. time, the C:END function could also be written like this.
  167.  
  168.     (defun C:END ()
  169.       (if
  170.         (eq "Y"
  171.             (strcase
  172.               (getstring "\nReally want to END the drawing? ")
  173.             )
  174.         )
  175.         (command ".END")
  176.         (prompt "\nRemaining in drawing editor.")
  177.       )
  178.       (prin1)
  179.     )
  180.  
  181. However, as you begin to learn AutoLISP, it's entirely
  182. appropriate for you to use as many variable bindings as you like
  183. if it helps you to keep things straight in your programs and your
  184. own mind.  There are all sorts of interesting things you can do
  185. in AutoLISP to write efficient code, but until you have a firm
  186. understanding of the basic mechanics, such an effort is likely to
  187. be counter-productive.  Who cares whether an additional 40
  188. milliseconds of computer time was consumed by a variable binding
  189. that strictly speaking didn't have to be there if it helps make
  190. the program logic easier for you to understand?
  191.  
  192. Next week: Part Two
  193.  
  194. Exercise
  195.  
  196. 1.  Write a new function HIGHER.  Here's what it should do.
  197.  
  198.     a)  Prompt the user to select two points.
  199.     b)  Store the values of both points.
  200.     c)  Test the Y values of both points.
  201.     d)  If the Y value of the first point is greater, print a
  202.         message telling the user the first point is higher.
  203.     e)  If the Y value of the second point is greater, print
  204.         a message telling the user the second point is higher.
  205.  
  206. Functions that you might want to use include GETPOINT, IF, DEFUN,
  207. CAR, CDR, and >.
  208.  
  209. Note that you could include two separate IF statements, or
  210. combine the two possible responses as the two expressions
  211. following the text expression in a single IF statement.  The
  212. latter case is typically referred to as an IF-THEN-ELSE
  213. statement.
  214.  
  215.     (if
  216.           < this test expression is true >
  217.           < then do this expression>
  218.           < else do this expression, instead>
  219.   )
  220.